/*package edu.whu.demo.service.impl;

import org.apache.tomcat.websocket.WsSession;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;

import static jdk.nashorn.internal.runtime.regexp.joni.Config.log;

@Component
@ServerEndpoint("/websocket")
public class WebSocket {
    private Session  session;

    private static CopyOnWriteArraySet<WebSocket> webSocketSet = new CopyOnWriteArraySet<>();

    @OnOpen
    public void onOpen(Session session){
        this.session = session;
        webSocketSet.add(this);
        //打印日志
    }

    @OnClose
    public void onClose(){
        webSocketSet.remove(this);
    }

    @OnMessage
    public void onMessage(String message){

    }

    public void sendMessage(String message){
        for (WebSocket webSocket : webSocketSet) {
            try {
                webSocket.session.getBasicRemote().sendText(message);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}*/
package edu.whu.demo.service.impl;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import lombok.extern.log4j.Log4j2;

import org.springframework.stereotype.Component;
/**

 * WebSocketServer

 *

 * @author zhengkai.blog.csdn.net
 */
@ServerEndpoint("/db/imserver/{userId}")
@Component
@Log4j2
public class WebSocket {
    //    static Log log=LogFactory.get(WebSocketServer.class);
    /** 静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。 */
    private static int onlineCount = 0;
    /** concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。 */
    private static ConcurrentHashMap<String, WebSocket> webSocketMap = new ConcurrentHashMap<>();
    /** 与某个客户端的连接会话，需要通过它来给客户端发送数据 */
    private Session session;
    /** 接收userId */
    private String userId = "";

    /**

     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        this.session = session;
        this.userId = userId;
        log.info("userId:"+userId);
        if (webSocketMap.containsKey(userId)) {
            webSocketMap.remove(userId);


            log.info("创建用户1");
            webSocketMap.put(userId, this);
            // 加入set中

        } else {
            log.info("创建用户2");
            webSocketMap.put(userId, this);
            // 加入set中
            addOnlineCount();
            // 在线数加1
        }

        log.info("用户连接:" + userId + ",当前在线人数为:" + getOnlineCount());

        try {


            Map<Object,Object> map = new HashMap<Object, Object>();
            map.put("code","1");
            map.put("msg","连接成功");
            map.put("data","内容");

            sendMessage(JSON.toJSONString(map));

            //			webSocketMap.get("1").sendMessage("niubi");
        } catch (IOException e) {
            //            log.error("用户:"+userId+",网络异常!!!!!!");
        }
    }

    /**

     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        if (webSocketMap.containsKey(userId)) {
            webSocketMap.remove(userId);
            // 从set中删除
            subOnlineCount();
        }
        log.info("用户退出:" + userId + ",当前在线人数为:" + getOnlineCount());
    }

    /**

     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     * @throws IOException
     */
    @OnMessage
    public void onMessage(String message, Session session) throws IOException {
        log.info("用户消息:" + userId + ",报文:" + message);
        log.info("11111111111111111111111111111111111111111111111111111111111111111111111111111111111");
        JSONObject wcAuthJson = JSON.parseObject(message);
        String toUserId = (String)wcAuthJson.get("toUserId");
        //		log.info("toUserId:"+wcAuthJson.get("toUserId"));
        String type = (String) wcAuthJson.get("type");
        //		log.info(toUserId+"===="+type);
        webSocketMap.get(toUserId).sendMessage(type);

    }


    /**
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {

//        log.error("用户错误:"+this.userId+",原因:"+error.getMessage());
//        error.printStackTrace();
    }

    /**
     * 实现服务器主动推送
     */
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }

    /**
     * 发送自定义消息
     */
    public static void sendInfo(String message, @PathParam("userId") String userId) throws IOException {
        log.info("发送消息到:" + userId + "，报文:" + message);
        if(userId.trim().length()>0&&webSocketMap.containsKey(userId)){
            webSocketMap.get(userId).sendMessage(message);
        }else{
            log.error("用户"+userId+",不在线！");
        }
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        WebSocket.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        WebSocket.onlineCount--;
    }

}
